package cn.rkylin.apollo.common.interceptor;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.alibaba.fastjson.JSON;

import cn.rkylin.apollo.common.util.BeanUtils;
import cn.rkylin.oms.common.context.CurrentUser;
import cn.rkylin.oms.common.context.WebContextFactory;
import cn.rkylin.oms.common.utils.CookieUtil;
import cn.rkylin.oms.system.facade.IOrganizationFacade;
import cn.rkylin.oms.system.facade.ResourceBean;
import cn.rkylin.oms.system.user.controller.UserController;

/**
 * 资源访问拦截器，用于判断url路径是否可以访问
 * 
 * @author wangxiaoyi
 *
 */
public class ResourceAccessInterceptor implements Filter {
    private static final Log logger = LogFactory.getLog(ResourceAccessInterceptor.class);
    
    // 不需要进行权限控制的html页面
    private String excludedPages;
    private String[] excludedPageArray;

    @Override
    public void destroy() {

    }

    /**
     * 页面权限过滤
     */
    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
        Map<String, String> resultMap = new HashMap<String, String>();
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponseWrapper response = new HttpServletResponseWrapper((HttpServletResponse) resp);

        boolean isExcludedPage = false;
        for (String page : excludedPageArray) {// 判断是否在过滤url之外
            if (((HttpServletRequest) request).getServletPath().equals(page)) {
                isExcludedPage = true;
                break;
            }
        }
        if (isExcludedPage) {// 在过滤url之外
            chain.doFilter(req, resp);
            return;
        }
        CurrentUser currUser = WebContextFactory.getWebContext().getCurrentUser();
        
        // 如果没有登录，就通过cookie进行登录
        if (currUser == null) {
            currUser = cookieLogin();
        }
        
        if (currUser == null || StringUtils.isBlank(currUser.getAccount())) {
            if ("POST".equalsIgnoreCase(request.getMethod())) {
                resultMap.put("result", "failed");
                resultMap.put("msg", "未登录，不能访问此资源");
                response.setContentType("text/html; charset=utf-8");
                PrintWriter out = response.getWriter();
                out.write(JSON.toJSONString(resultMap));
                out.flush();
                out.close();
            } else {
                response.sendRedirect(request.getContextPath() + "/login.html");
            }
            chain.doFilter(req, resp);
            return;
        } else {
            // 忽略特殊的连接
            if (isSpecialLinks(request.getRequestURI())) {
                chain.doFilter(req, resp);
                return;
            }
            
            boolean hasPermission = false;
            for (ResourceBean rb : currUser.getAvailableMenus()) {
                if (StringUtils.isEmpty(rb.getResourceLocation())) {
                    continue;
                }
                // 忽略“菜单管理”里面配置的“?xx=yy”。
                String rbLocation = rb.getResourceLocation();
                if (rbLocation.indexOf("?") > 0) {
                    rbLocation = rbLocation.substring(0, rb.getResourceLocation().indexOf("?"));
                }
                if (rbLocation.equalsIgnoreCase(request.getRequestURI())) {
                    hasPermission = true;
                    break;
                }
            }
            // 有页面权限或者是adminUser不过滤页面权限
            if (hasPermission) {
                chain.doFilter(req, resp);
                return;// 正常通过
            } else {
                resultMap.put("result", "failed");
                resultMap.put("msg", "无此资源访问权限");
                response.setContentType("text/html; charset=utf-8");
                // PrintWriter out = response.getWriter();
                // out.write(JSON.toJSONString(resultMap));
                // out.flush();
                // out.close();
                request.getRequestDispatcher("/AccessDenied.html").forward(request, response);

                return;
            }
        }

    }

    /**
     * 通过cookie登录
     * @return
     */
    private CurrentUser cookieLogin() {
        CookieUtil cookieUtil = new CookieUtil();
        CurrentUser returnUser = cookieUtil.getCurrentUserCookie();
        if (StringUtils.isNotBlank(returnUser.getAccount())) {// && StringUtils.isNotBlank(returnUser.getPassword())) {
            try {
                IOrganizationFacade orgFacade = BeanUtils.getBean("orgFacade");
                returnUser = orgFacade.getCurrentUser(returnUser.getAccount(), returnUser.getPassword(), true, true, false, true, false);
                WebContextFactory.getWebContext().setCurrentUser(returnUser);
            } catch (Exception ex) {
                logger.error("用cookie登录时发生错误", ex);
            }
        }
        return returnUser;
    }

    /**
     * 判断是否是特殊连接，即可以忽略的连接，比如druid界面
     * @param location
     * @return
     */
    private boolean isSpecialLinks(String location) {
        // 特殊连接检测，比如druid管理界面，先写死吧，如果有大量灵活需求再改
        if (location.indexOf("/druid/") > -1) {
            return true;
        }
        return false;
    }

    /**
     * 初始化过滤器，把web.xml里的过滤器参数组装起来
     */
    @Override
    public void init(FilterConfig fConfig) throws ServletException {
        excludedPages = fConfig.getInitParameter("excludedPages");
        if (StringUtils.isNotEmpty(excludedPages)) {
            excludedPageArray = excludedPages.split(",");
        }
        return;
    }

}
